package cn.xshi.common.advice;

import cn.xshi.common.base.BasePage;
import cn.xshi.common.base.BaseResult;
import cn.xshi.common.util.JsonUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import cn.xshi.common.annotation.NeedHttpEncrypt;
import cn.xshi.common.util.DecryptUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
/**
 * @Desc 全局参数加密
 * @Author 邓纯杰
 * @CreateTime 2012-12-12 12:12:12
 */
@Slf4j
@ControllerAdvice
public class HttpResponseBodyAdvice implements ResponseBodyAdvice {
    /**
     *
     * @param arg0
     * @param arg1
     * @return
     */
    @Override
    public boolean supports(MethodParameter arg0, Class arg1) {
        boolean methodNeedHttpBodyDecrypt = arg0.hasMethodAnnotation(NeedHttpEncrypt.class);//需要加密注解
        if (methodNeedHttpBodyDecrypt) {
            log.info("supports");
            return true;
        }
        boolean classNeedHttpBodyDecrypt = arg0.getDeclaringClass().getAnnotation(NeedHttpEncrypt.class) != null;//需要加密注解
        if (classNeedHttpBodyDecrypt) {
            log.info("supports");
            return true;
        }
        return false;
    }

    /**
     * 加密传输 并通知客户端数据为加密数据
     * @param object
     * @param methodParameter
     * @param mediaType
     * @param aClass
     * @param request
     * @param response
     * @return
     */
    @Override
    public Object beforeBodyWrite(Object object, MethodParameter methodParameter, MediaType mediaType,
                                  Class aClass, ServerHttpRequest request, ServerHttpResponse response) {
        try {
            response.getHeaders().add("encrypt", "true");//创建encrypt header，通知客户端数据已加密
            String data = JSON.toJSONString(object);
            if(object instanceof BasePage){
                BasePage basePage = JsonUtil.fromFastJson(object,BasePage.class);
                if(null != basePage.getData()){
                    String dataEncrypt = DecryptUtils.encrypt(JSONArray.toJSONString(basePage.getData()));//对data进行加密传输
                    basePage.setData(dataEncrypt);
                    log.info("原数据：{},加密后数据：{}", data, basePage.getData());
                    return basePage;
                }
            }else if(object instanceof BaseResult){
                BaseResult baseResult = JsonUtil.fromFastJson(object,BaseResult.class);
                if(null != baseResult.getData()){
                    String dataEncrypt = DecryptUtils.encrypt(JSON.toJSONString(baseResult.getData()));//对data进行加密传输
                    baseResult.setData(dataEncrypt);
                    log.info("原数据：{},加密后数据：{}", data, baseResult.getData());
                    return baseResult;
                }
            }else{
                String dataEncrypt = DecryptUtils.encrypt(data);//对data进行加密传输
                log.info("原数据：{},加密后数据：{}", data, dataEncrypt);
                return dataEncrypt;
            }
        } catch (Exception e) {
            log.error("异常！", e);
            return BaseResult.fail();
        }
        return BaseResult.success();
    }
}
